#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2023/3/4 21:42
# @Author : Sugar丶fate


# https://blog.csdn.net/qq_31823267/article/details/78502930?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167793613316800180643648%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=167793613316800180643648&biz_id=&utm_medium=distribute.pc_search_result.none-task-code-2~all~first_rank_ecpm_v1~rank_v31_ecpm-11-78502930-4-null-null.142^v73^wechat_v2,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=%E8%BD%A8%E8%BF%B9%E5%8E%8B%E7%BC%A9dp%E7%AE%97%E6%B3%95%20python
import math

def Distance(lon_1,lat_1,lon_2,lat_2):
    R = 6378137 # 地球半径·
    lat_1 = lat_1 * math.pi/180
    lat_2 = lat_2 * math.pi/180
    dater_lat = lat_1 - lat_2
    dater_lon = (lon_1-lon_2)*math.pi/180
    s_lat = math.sin(dater_lat/2)
    s_lon = math.sin(dater_lon/2)
    d = 2 * R * math.asin(math.sqrt(s_lat**2 + math.cos(lat_1)*math.cos(lat_2)*s_lon**2))
    return d

def get_vertical_dist(df,start_index,end_index,index):  # 得到垂直距离

    a=math.fabs(Distance(df['lon'][start_index],df['lat'][start_index],df['lon'][end_index],df['lat'][end_index])) # 开始结束两点间的距离

    #当弦两端重合时,点到弦的距离变为点间距离
    if a==0:
        return math.fabs(Distance(df['lon'][start_index],df['lat'][start_index],df['lon'][index],df['lat'][index]))

    b=math.fabs(Distance(df['lon'][start_index],df['lat'][start_index],df['lon'][index],df['lat'][index]))
    c=math.fabs(Distance(df['lon'][end_index],df['lat'][end_index],df['lon'][index],df['lat'][index]))
    p=(a+b+c)/2
    S=math.sqrt(math.fabs(p*(p-a)*(p-b)*(p-c)))

    vertical_dist=S*2/a

    return vertical_dist


def DP_compress(df,output_point_list,Dmax):
    start_index = 0
    end_index = len(df['lon']) - 1
    # 起止点必定是关键点,但是作为递归程序此步引入了冗余数据,后期必须去除
    output_point_list.append(df.iloc[start_index].values)
    output_point_list.append(df.iloc[end_index].values)


    if start_index<end_index:
        index=start_index+1        #工作指针,遍历除起止点外的所有点
        max_vertical_dist=0        #路径中离弦最远的距离
        key_point_index=0        #路径中离弦最远的点,即划分点

        while (index < end_index):
            cur_vertical_dist = get_vertical_dist(df,start_index,end_index,index)
            if cur_vertical_dist > max_vertical_dist:
                max_vertical_dist = cur_vertical_dist
                key_point_index = index  # 记录划分点
            index += 1

            # 递归划分路径
            if max_vertical_dist >= Dmax:
                DP_compress(df[start_index:key_point_index], output_point_list, Dmax)
                DP_compress(df[key_point_index:end_index], output_point_list, Dmax)


#4.平均误差


import pandas as pd
import matplotlib.pyplot as plt
fd = open('D:\python\python_data\轨迹压缩\临时数据.csv')
fd = pd.read_csv(fd)
fd.columns=['mmsi','lon','lat','v','c','time']

res = fd.sort_values(by='time')
print(res)
# print(res)
# plt.plot(res['lon'],res['lat'])
# # plt.plot(fd['lon'],fd['lat'])
# plt.show()
#
# df = fd['lon']
# df1 = fd['lat']

output_point_list = DP_compress(res,output_point_list=[],Dmax=5)
print(output_point_list)


# https://zhuanlan.zhihu.com/p/136286488